Skip to content

fix(website): blog links resolve from /blog, assets are cache-busted - #327

Merged
vsilent merged 1 commit into
mainfrom
fix/blog-links-and-asset-cache
Nov 6, 2026
Merged

vsilent merged 1 commit into
mainfrom
fix/blog-links-and-asset-cache

Conversation

@vsilent

@vsilent vsilent commented Nov 6, 2026

Copy link
Copy Markdown
Collaborator

Two production bugs on stacker.my/blog (both reproduced locally and root-caused this session):

1. Article click landed on /ai-startup-hosting (404). The canonical URL is /blog (serve's clean-URL redirects: /blog/index.html -> /blog/index -> /blog), so the page's relative href="ai-startup-hosting.html" resolved against /. The article and Blog nav/footer links are now root-absolute (4 hrefs in website/src/blog/index.html, synced to dist).

2. Layout broken after the last deploy. curl https://stacker.my/styles.css served the pre-blog stylesheet (32247 bytes = git show 949a0c4d^:website/src/styles.css, cf-cache-status: HIT, age: 4821, cache-control: max-age=14400) while the HTML was current - new blog markup + old CSS. A CF purge alone would not fix it (browsers hold it up to 4h), so built HTML now references styles.css/main.js with a content-hashed ?v= via website/scripts/bust-assets.mjs, wired into npm run build. The next deploy reaches every visitor immediately, no cache purge needed.

Regression test website/tests/serving.mjs extended - served from /blog it asserts: every internal link fetches a served page, the article title link lands on the article, the Blog nav link lands on the blog index, and the stylesheet is cache-busted and defines the blog styles. Verified fail-before (4 FAILs matching the production symptoms) / pass-after (7 PASS), plus a Docker image build producing href="/blog/ai-startup-hosting.html" and styles.css?v=a27cd226 in its dist.

Note: dist HTML intentionally carries the ?v= while src keeps plain refs - the build injects the hash.

The canonical blog URL is /blog (serve's clean-URL redirects drop the
trailing slash), so the blog index's relative links resolved against /
and the article click landed on /ai-startup-hosting (404). The article
and Blog nav/footer links are now root-absolute.

Built HTML now references styles.css and main.js with a content-hashed
?v= (scripts/bust-assets.mjs, wired into npm run build) so CDN and
browser caches cannot keep serving the previous stylesheet across
deploys - that staleness is what broke the blog layout after the last
deploy (live styles.css matched the pre-blog file).

Regression test website/tests/serving.mjs asserts, served from /blog:
every internal link fetches a page, the article link lands on the
article, the Blog nav link lands on the blog index, and the stylesheet
is cache-busted and defines the blog styles.
@vsilent
vsilent merged commit 32346be into main Nov 6, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants